#ifndef _CAPTURE_HPP_
#define _CAPTURE_HPP_

#define __STDC_CONSTANT_MACROS
extern "C"
{
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
}

#include <opencv2/opencv.hpp>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <queue>

namespace gentech
{

class CAVPacketQueue
{
public:
	CAVPacketQueue() {}

	~CAVPacketQueue();

	void push(AVPacket &pkt);

	bool pop_front(AVPacket &pkt);

	void set_abort(int abort);

private:
	std::condition_variable cv_;
	std::mutex mtx_;
	std::queue<AVPacket> pkt_queue_;
	int abort_;
};

struct SCaptureParam
{
	std::string str_video_path_;
};

class CCapture
{
public:
	CCapture();

	~CCapture();

	bool init(SCaptureParam &capture_param);

	bool capture(cv::Mat &frame);

	void close();

private:
	void read_packet();

private:
	AVFormatContext *pFormatCtx_;
	int videoStreamIndex_;
	AVCodecContext *pVideoCodecCtx_;
	struct SwsContext *pSwsCtx_;
	AVFrame *pVideoFrame_, *pBGRVideoFrame_;

	CAVPacketQueue pkt_queue_;
	std::mutex read_packet_thread_exit_mtx_;
	std::condition_variable read_packet_thread_exit_cv_;
	std::atomic<bool> read_packet_thread_exit_;
	std::atomic<bool> abort_read_packet_thread_;
};

}

#endif // _CAPTURE_HPP_